iT邦幫忙

2024 iThome 鐵人賽

DAY 28
0
Kubernetes

異世界生存戰記:30天煉成GKE大師系列 第 28

Day28 在 GKE TPU 異世界中轉職為詠唱師:Gemma LLM 部署實戰

  • 分享至 

  • xImage
  •  

https://ithelp.ithome.com.tw/upload/images/20241012/201690170zdv1IQ5Tm.png

前言

前面幾篇文章介紹了 GKE Nvidia GPU 的應用,今天將要介紹一個特殊硬體 TPU 的應用。將引導您如何在 Google Kubernetes Engine (GKE) 上使用 TPU 節點部署 Gemma 7B 輕量級大型語言模型,並透過 JetStream 推理服務框架和 Gradio 介面,構建一個高效能的問答系統。

文章涵蓋了設置 TPU GKE 節點池、獲取 Gemma 模型訪問權限、轉換模型檢查點到部署 JetStream 和 Gradio 的完整流程。

我們將利用 TPU v5e 的強大算力,結合 JetStream 的優化策略,最大化 Gemma 模型的性能。

GKE TPU Node Pool 介紹

TPU 是 Google 定製開發的應用專用積體電路 (ASIC),用於加速機器學習和使用 TensorFlowPyTorch 和 JAX 等框架構建的 AI 模型。

主要有兩種 TPU 節點池:

  • 單主機 TPU 切片節點池: 此類節點池包含一個或多個獨立的 TPU 虛擬機 (VM)。每個虛擬機都連接到一個 TPU 設備。雖然單主機切片節點池中的虛擬機可以通過數據中心網絡 (DCN) 進行通信,但連接到虛擬機的 TPU 並未互連。適用於單個 TPU 設備即可處理的工作負載。
  • 多主機 TPU 切片節點池: 此類節點池包含兩個或多個互連的 TPU 虛擬機。每個虛擬機都連接到一個 TPU 設備,這些 TPU 通過高速互連 (ICI) 連接,形成一個更大的 TPU 切片,提供更高的計算能力。適用於需要多個 TPU 協同工作的大規模工作負載。需要注意的是,多主機 TPU 切片節點池創建後,無法再添加節點。

使用 TPU GKE 節點池:

  • 多種 TPU 版本和大小: GKE 支持各種 TPU 版本(例如 v4、v5e、v5p)和大小,您可以根據工作負載需求選擇合适的配置。
  • 在創建節點池之前,您需要選擇 TPU 版本和 TPU 切片的大小。
  • GKE 會將多主機 TPU 切片中的虛擬機視為一個原子單元。如果 GKE 無法部署切片中的一個節點,則不會部署 TPU 切片節點池中的任何節點。

Gemma LLM 介紹

Gemma 是一個由 Google AI 開發的輕量級開源大型語言模型 (LLM) 系列。它有兩個主要版本:2B 參數和 7B 參數的模型,每個版本都包含一個基本預訓練模型和一個指令微調模型。本文示範使用 7B 參數的 Gemma

以下是 Gemma 的一些主要特性:

  • 高效能: 儘管模型尺寸較小,Gemma 在各種自然語言處理任務上展現出強大的通用能力和最先進的理解和推理能力,包括文本摘要、問答、推理、數學和程式碼生成。尤其 7B 模型的性能表現優於 Mistral-7B 和 Llama-7B,接近 Llama 2 70B 的水準。
  • 硬體優化: Gemma 已經針對 Nvidia 和 TPU 進行了優化,並提供 GGUF 模型,以便在優化的推理模型上使用。

Gemma 作為一個輕量級、開源且高效能的 LLM,為自然語言處理領域的研究和應用提供了新的選擇,尤其是在資源受限的環境下。隨著模型的進一步發展和社群的貢獻,Gemma 的應用前景將更加廣闊。需要注意的是,儘管 Gemma 支援繁體中文問答,但生成的文本可能包含簡體中文。

JetStream 介紹

JetStream 是由 Google 開發的一款開源推理服務框架。 它專門針對大型語言模型(LLM)的輸送量和記憶體進行了優化,旨在提高開源模型的單位美元性能,並相容 JAX 和 PyTorch/XLA 框架,從而降低成本並提高效率。 JetStream 可以在 TPU上實現高性能。

創建 GKE TPU Node Pool

在創建 TPU 機器之前,請先到 IAM > Quota(配額與系統限制) 申請 TPU 的機器數量,篩選列中輸入 TPU v5 Lite Podslice chips,填入 8 以上,根據需求下圖中兩項 Preemptible一般,擇一申請即可,分別代表的是 Spot 機器on-demand 機器

https://ithelp.ithome.com.tw/upload/images/20241012/201690176JOtkKQlk2.png
使用 Day3 範例創建的Cluster,再創建一個具有 2x4 拓撲 1 個節點的 TPU v5e x 8 的 Node Pool。


module "gke" {
  node_pools = [
    var.gemma-7b-tpu.config,
  ]

  node_pools_labels = {
    "${var.gemma-7b-tpu.config.name}" = var.gemma-7b-tpu.kubernetes_label
  }

  node_pools_taints = {
    "${var.gemma-7b-tpu.config.name}" = var.gemma-7b-tpu.taints
  }

  node_pools_resource_labels = {
    "${var.gemma-7b-tpu.config.name}" = var.gemma-7b-tpu.node_pools_resource_labels
  }

}
variable "gemma-7b-tpu" {
  default = {
    config = {
      name               = "gemma-7b-tpu"
      machine_type       = "ct5lp-hightpu-8t"
      node_locations     = "us-central1-a"
      autoscaling        = false
      node_count         = 1
      local_ssd_count    = 0
      disk_size_gb       = 200
      spot               = true
      disk_type          = "pd-ssd"
      image_type         = "COS_CONTAINERD"
      enable_gcfs        = false
      enable_gvnic       = false
      logging_variant    = "DEFAULT"
      auto_repair        = true
      auto_upgrade       = true
      preemptible        = false
    }
      node_pools_resource_labels = {}
      kubernetes_label = {
        role = "gemma-7b-tpu"
      }
      taints = []
    }
}

創建出的 TPU Node Pool 會有以下兩個特殊標籤:

  • cloud.google.com/gke-tpu-topology: 2x4
  • cloud.google.com/gke-tpu-accelerator: tpu-v5-lite-podslice

獲取對模型的訪問權限

如需訪問 Gemma 模型以部署到 GKE,您必須先簽署許可同意協議。

簽署許可同意協議

您必須簽署同意協議才能使用 Gemma。 請按照以下說明操作:

  1. 訪問 Kaggle.com 上的 Gemma 模型同意頁面
  2. 申請訪問權限。
  3. 在 Choose Account for Consent(選擇進行同意的賬號)部分中,選擇 Verify via Kaggle Account(通過 Kaggle 賬號驗證),以使用您的 Kaggle 賬號進行同意。
  4. 接受模型條款及條件。

生成一個訪問令牌

如需通過 Kaggle 訪問模型,您需要 Kaggle API 令牌。

如果您還沒有令牌,請按照以下步驟生成新令牌:

  1. 進入 Kaggle 設置頁面。
  2. 在 API 部分下,點擊 Create New Token(創建新令牌)。

https://ithelp.ithome.com.tw/upload/images/20241012/20169017jttgT5Cgrn.png

系統將下載名為 kaggle.json 的文件,並使用以下指令將 kaggle.json 保存到 GKE 的 Secret 物件中。

$ kubectl create secret generic kaggle-secret -n ai \
    --from-file=kaggle.json

建立 GCS Bucket

https://ithelp.ithome.com.tw/upload/images/20241012/20169017HpSlBeZCUu.png

建立 GKE IAM Workload Identity

使用 Day6 的教學,在 ai Namespace 下創建 K8s SA demo-ai-cluster-general 使其和 GCP SA demo-ai-cluster-general 綁定,具有 roles/storage.insightsCollectorServiceroles/storage.objectAdmin的權限,因為筆者有跨專案存取 GCS ,所以將 GCS 所在的專案名稱及權限填在這裡 additional_projects

    ## Service account
    ai = {
      gcp_service_account           = "demo-ai-cluster-general"
      k8s_service_account           = "demo-ai-cluster-general"
      k8s_service_account_namespace = "ai"
      use_existing_gcp_sa           = false
      use_existing_k8s_sa           = false
      roles = [],
      
      # 填入管理 GCS 所在的專案
      additional_projects = {
        "ithome-202409-demo" = [
          "roles/storage.insightsCollectorService",
          "roles/storage.objectAdmin"
        ]
      }
    },

創建一個訓練使用的 Job

  1. 從 Kaggle 下載基礎 Orbax 檢查點。
  2. 將檢查點上傳到 Cloud Storage 存儲桶。
  3. 將檢查點轉換為與 MaxText 兼容的檢查點。
  4. 取消掃描要用於傳送的檢查點。

部署模型檢查點轉換 Job

  1. spec.template.spec.containers.args 中的 -b 後參數更改為 $GCS_BUCKET_名稱
  2. spec.template.spec.serviceAccountName 更改為具有 GCS 權限的 K8s Service Account。
  3. spec.template.spec.nodeSelector使用上面創建的 2x4 拓撲的 TPU v5e Node Pool。

gemma-7b-job.yaml

# gemma-7b-job.yaml
apiVersion: batch/v1
kind: Job
metadata:
  name: data-loader-7b
  namespace: ai
spec:
  ttlSecondsAfterFinished: 3600 # 1 小時後刪除
  template:
    spec:
      # 填入剛剛創建的 K8s SA 具有 GCS 物件擁有者權限
      serviceAccountName: $K8s_Service_Account
      restartPolicy: Never
      containers:
      - name: inference-checkpoint
        image: us-docker.pkg.dev/cloud-tpu-images/inference/inference-checkpoint:v0.2.2
        args:
        - -b=$GCS_BUCKET_Name
        - -m=google/gemma/maxtext/7b-it/2
        volumeMounts:
        - mountPath: "/kaggle/"
          name: kaggle-credentials
          readOnly: true
        resources:
          requests:
            google.com/tpu: 8
          limits:
            google.com/tpu: 8
      nodeSelector:
        cloud.google.com/gke-tpu-topology: 2x4
        cloud.google.com/gke-tpu-accelerator: tpu-v5-lite-podslice
# 掛載 kaggle-secret
      volumes:
      - name: kaggle-credentials
        secret:
          defaultMode: 0400
          secretName: kaggle-secret

大約經過七分鐘後可以訓練完成,使用指令確認 Job Logs,kubectl logs $Job_PodName -n ai

$ kubectl logs $Job_PodName -n ai

## ...以上省略...
saved an decode checkpoint at gs://$GCS_BUCKET_Name/final/unscanned/gemma_7b-it/0/checkpoints/
Successfully generated decode checkpoint at: gs://$GCS_BUCKET_Name/final/unscanned/gemma_7b-it/0/checkpoints/0/items

Completed unscanning checkpoint to gs://$GCS_BUCKET_Name/final/unscanned/gemma_7b-it/0/checkpoints/0/items

部署 Gemma 推論模型

我們將部署 JetStream 容器來應用 Gemma 模型,使用以下指令創建 jetstream-gemma-deployment.yamlService-Ingress.yaml 檔案

$ kubectl apply -f jetstream-gemma-deployment.yaml
$ kubectl apply -f service-ingress.yaml

jetstream-gemma-deployment.yaml 中的 args 這些參數用於配置maxengine-server

  • model_name=gemma-7b: 指定要使用的模型名稱為 Gemma 7B,擁有 70 億個參數,讀者也可以將此改為使用 20 億個參數的 Gemma gemma-2b
  • per_device_batch_size=4: 設定每個設備(例如:TPU 核心)的批量大小為 4。這意味著每個設備會同時處理 4 個輸入序列。
  • max_prefill_predict_length=1024: 設定預填充(prefill)階段的最大預測長度為 1024 個 token。預填充通常指模型在生成文本的初始階段,使用已知的上下文信息來生成一部分文本。
  • max_target_length=2048: 設定目標序列的最大長度為 2048 個 token。這限制了模型生成文本的最大長度。
  • async_checkpointing=false: 不使用異步檢查點。
  • ici_tensor_parallelism=1: 設定張量並行度為 1。張量並行是一種用於訓練大型模型的並行化技術,它將模型的參數分佈到多個設備上。
  • weight_dtype=bfloat16: 設定模型權重的數據類型為 bfloat16。bfloat16 是一種 16 位浮點數格式,可以提高訓練速度並減少內存使用。
  • load_parameters_path=gs://$GCS_Bucket_Name/final/unscanned/gemma_7b-it/0/checkpoints/0/items: 指定模型參數的加載路徑。這裡的路徑指向 Google Cloud Storage (GCS) 上的一個位置。

讀者可以根據需求修改以上的參數。

# jetstream-gemma-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: maxengine-server
  namespace: ai
spec:
  replicas: 1
  selector:
    matchLabels:
      app: maxengine-server
  template:
    metadata:
      labels:
        app: maxengine-server
    spec:
      # 填入剛剛創建的 K8s SA 具有 GCS 物件擁有者權限
      serviceAccountName: $K8s_Service_Account
      nodeSelector:
        cloud.google.com/gke-tpu-topology: 2x4
        cloud.google.com/gke-tpu-accelerator: tpu-v5-lite-podslice
      containers:
      - name: maxengine-server
        image: us-docker.pkg.dev/cloud-tpu-images/inference/maxengine-server:v0.2.2
        args:
        - model_name=gemma-7b
        - tokenizer_path=assets/tokenizer.gemma
        - per_device_batch_size=4
        - max_prefill_predict_length=1024
        - max_target_length=2048
        - async_checkpointing=false
        - ici_fsdp_parallelism=1
        - ici_autoregressive_parallelism=-1
        - ici_tensor_parallelism=1
        - scan_layers=false
        - weight_dtype=bfloat16
        - load_parameters_path=gs://$GCS_Bucket_Name/final/unscanned/gemma_7b-it/0/checkpoints/0/items
        ports:
        - containerPort: 9000
        resources:
          requests:
            google.com/tpu: 8
          limits:
            google.com/tpu: 8
      - name: jetstream-http
        image: us-docker.pkg.dev/cloud-tpu-images/inference/jetstream-http:v0.2.2
        ports:
        - containerPort: 8000

Service-Ingress.yaml

# Service-Ingress.yaml
apiVersion: v1
kind: Service
metadata:
  name: jetstream-svc
  namespace: ai
spec:
  selector:
    app: maxengine-server
  ports:
  - protocol: TCP
    name: jetstream-http
    port: 8000
    targetPort: 8000
  - protocol: TCP
    name: jetstream-grpc
    port: 9000
    targetPort: 9000
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: gemma
  namespace: ai
  annotations:
    cert-manager.io/cluster-issuer: letsencrypt-demo
spec:
  ingressClassName: external-nginx
  tls:
    - hosts:
        - gemma.demoit.shop
      secretName: gemma-tls
  rules:
    - host: "gemma.demoit.shop"
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: jetstream-svc
                port:
                  number: 8000

使用 Gradio 部署 Web UI 聊天介面

Gradio 介紹

Gradio 是一個 Python 函式庫,可以快速輕鬆地創建用於機器學習模型、API 或任何 Python 函數的使用者介面。僅用幾行程式碼就將你的程式碼轉變成一個互動式的網頁應用程式,讓使用者可以輸入資料(例如文字、圖片、聲音),查看模型的輸出,並分享演示給其他人。

特別適合用於演示機器學習模型,Gradio 的主要優點是它的簡潔性和易用性。不需要了解網頁開發的知識,就可以創建出美觀且功能強大的使用者介面。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: gradio
  namespace: ai
  labels:
    app: gradio
spec:
  replicas: 1
  selector:
    matchLabels:
      app: gradio
  template:
    metadata:
      labels:
        app: gradio
    spec:
      containers:
      - name: gradio
        image: us-docker.pkg.dev/google-samples/containers/gke/gradio-app:v1.0.3
        resources:
          requests:
            cpu: "512m"
            memory: "512Mi"
          limits:
            cpu: "1"
            memory: "512Mi"
        env:
        - name: CONTEXT_PATH
          value: "/generate"
        - name: HOST
        # 改成 K8s 內部 Jetstream Service 的 DNS 紀錄
          value: "http://jetstream-svc.ai.svc:8000"
        - name: LLM_ENGINE
          value: "max"
        - name: MODEL_ID
          value: "gradio-gemma"
        - name: USER_PROMPT
          value: "<start_of_turn>user\nprompt<end_of_turn>\n"
        - name: SYSTEM_PROMPT
          value: "<start_of_turn>model\nprompt<end_of_turn>\n"
        ports:
        - containerPort: 7860
---
apiVersion: v1
kind: Service
metadata:
  name: gradio
  namespace: ai
spec:
  selector:
    app: gradio
  ports:
    - protocol: TCP
      port: 7860
      targetPort: 7860
  type: ClusterIP
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: gradio-gemma
  namespace: ai
  annotations:
    cert-manager.io/cluster-issuer: letsencrypt-demo
spec:
  ingressClassName: external-nginx
  tls:
    - hosts:
        - gradio-gemma.demoit.shop
      secretName: gradio-gemma-tls
  rules:
    - host: "gradio-gemma.demoit.shop"
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: gradio
                port:
                  number: 7860

等待部署完成後,進入網頁,可以看到輸入 Prompt 的欄位,

https://ithelp.ithome.com.tw/upload/images/20241012/20169017eyBuDDrV7n.png

總結

本文詳細介紹了如何在GKE上部署Gemma 7B模型,並利用JetStream和Gradio構建一個可用的聊天機器人。

文章從TPU節點池的選擇和創建開始,逐步引導讀者完成模型的訪問授權、數據準備、模型轉換和部署等關鍵步驟。

此外,文章還整合了 Workload Identity 和 GCS 等相關知識,使整個部署流程更加完整和易於理解。

即使本文篇幅較長,讀者只需按步驟操作,即可輕鬆在 GKE 上部署 TPU 節點並運行 Gemma 模型,親身體驗 TPU 的強大效能。

參考文件


上一篇
Day27 模型神速啟動!Local SSD 究極奧義,開啟 AI 推論的超次元通道
下一篇
Day29 GKE 艦隊大軍集結:串連跨區域高可用多集群服務
系列文
異世界生存戰記:30天煉成GKE大師30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言